package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

// 一般的 go语言中 返回多个参数的情况下，第二个值一般是 error
func eval(a, b int, op string) (int, error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		return a / b, nil
	default:
		return 0, fmt.Errorf("传入了一个不认识的操作符：%s", op)
	}
}

func div(a, b int) (q, r int) {
	return a / b, a % b
}

func apply(op func(int, int) int, a, b int) int {
	// 通过反射拿op的名称
	p := reflect.ValueOf(op).Pointer()
	funcName := runtime.FuncForPC(p).Name()
	fmt.Printf("calling %s with %d, %d\n", funcName, a, b)

	return op(a, b)
}

func sums(nums ...int) int {
	result := 0
	for i := range nums {
		result += nums[i]
	}
	return result
}

func main() {
	if result, err := eval(1, 2, "x"); err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(result)
	}
	fmt.Println(div(13, 3))

	fmt.Println(
		apply(
			func(a, b int) int {
				return int(math.Pow(float64(a), float64(b)))
			}, 3, 4))

	fmt.Println(sums(1, 2, 3, 4))
}
